﻿namespace ufida.u9.ait.openapi
{
	using System;
	using System.Collections.Generic;
	using System.Text;
    using ufida.u9.ait.openapi.utils;
    using UFIDA.U9.Base.SOB;
    using UFIDA.U9.CBO.FI.Account;
    using UFIDA.U9.CBO.FI.BankAccount;
    using UFIDA.U9.CBO.Pub.Controller;
    using UFIDA.U9.GL.Voucher;
    using UFIDA.U9.ISV.GL.ISVGLImportSV;
    using UFIDA.U9.ISV.GL.ISVGLImportSV.Proxy;
    using UFSoft.UBF.AopFrame;
    using UFSoft.UBF.Business;
    using UFSoft.UBF.Util.Context;

	/// <summary>
	/// VoucherSaveSV partial 
	/// </summary>	
	public partial class VoucherSaveSV 
	{	
		internal BaseStrategy Select()
		{
			return new VoucherSaveSVImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class VoucherSaveSVImpementStrategy : BaseStrategy
	{
		public VoucherSaveSVImpementStrategy() { }

		public override object Do(object obj)
		{						
			VoucherSaveSV bpObj = (VoucherSaveSV)obj;

			try
			{
				if (bpObj.Data == null || bpObj.Data.Count == 0)
					throw new Exception("传入参数为空");
				List<ISVReturnVoucherDTOData> retlist = new List<ISVReturnVoucherDTOData>();

				List<object> inputdtos = DTOUtils.DTOListPropCopy(bpObj.Data.ConvertAll(item => item as object)
					, typeof(ISVImportVoucherDTOData));
				
				foreach (ISVImportVoucherDTOData dto in inputdtos)
				{
					//传入的外部凭证号放入[ThirdVcouherNo]字段中
					//查询凭证是否已经存在
					Voucher item = Voucher.Finder.Find($"ThirdVcouherNo='{dto.VoucherDisplayCode}'");
					if (item == null)
                    {
						//新增逻辑,调用产业链服务
						PreSave(dto);
                        ISVGLImportSVProxy proxy = new ISVGLImportSVProxy();
                        proxy.ImportVoucherDTOs = new List<ISVImportVoucherDTOData> { dto };
                        List<ISVReturnVoucherDTOData> ret = proxy.Do();
                        //修改凭证号
                        using (ISession se = Session.Open())
                        {
                            Voucher doc = Voucher.Finder.FindByID(ret[0].VoucherID);
                            if (doc != null)
                            {
                                doc.ThirdVcouherNo = dto.VoucherDisplayCode;
                                se.Commit();
                            }
                        }
                        
                        //处理返回值
                        if (ret.Count > 0)
                        {
                            ret[0].DocNo = dto.VoucherDisplayCode;
                            retlist.Add(ret[0]);
                        }

                    }
                    else
					{
						//修改逻辑
						throw new AITException(599,$"单号:{dto.VoucherDisplayCode}已经存在,不能生成!");
					}
				}
				return ResultUtils.success(bpObj, bpObj.Data, retlist);
			}
			catch (Exception ex)
			{
				return ResultUtils.error(bpObj, bpObj.Data, ex);
			}
		}

        private void PreSave(ISVImportVoucherDTOData dto)
        {
			//头处理
			//账簿/记账期间处理
            //SetofBooks sob = EntityUtils.GetEntityByCode<SetofBooks>(dto.SOB.Code);
            SetofBooks sob = EntityUtils.getSetofBooks();
			dto.SOB = new CommonArchiveDataDTOData()
			{
				ID = sob.ID,
				Code = sob.Code,
			};
            SOBAccountingPeriod period = EntityUtils.getPostPeriod(dto.CreateDate);
			dto.PostedPeriod = period.DisplayName;

			//凭证分录
            foreach (var line in dto.Entries)
            {
				//预置数据
				line.Voucher = dto;
				//币种
				if (line.Currency == null)
				{
					line.Currency = new CommonArchiveDataDTOData()
					{
						Code = "C001"
					};
				}

				//金额
				if(line.AccountedDr==0)
					line.AccountedDr = line.EnteredDr;//借方金额
				if(line.AccountedCr==0)
					line.AccountedCr = line.EnteredCr;//贷方金额

                //查找或创建会计科目
                Account account = this.FindAccount(line.Account, sob.ID, -1);
                //爱发科逻辑,依据科目获取银行账号
                if (account.IsBankAccount)
                {
					BankAccount bacc = EntityUtils.GetEntityByPath<BankAccount>($"DescFlexField.PrivateDescSeg1='{account.Segment1}'");
					line.BankAccount = new CommonArchiveDataDTOData
					{
						Code = bacc.Code,
					};
				}

                //ImportType 凭证导入方式 0-头和分录 1-全部
                if (dto.ImportType == 1)
                {
					//如果是全量导入,含现金流量项目
					//现金流量项目 处理逻辑
					if (account != null && account.IsMainTableCashFlowAccount)
					{
						ISVImportCFVoucherItemDTOData cfdto = new ISVImportCFVoucherItemDTOData();
						cfdto.Voucher = dto;
						cfdto.VoucherEntry = line;
						cfdto.OCMoney = line.EnteredCr + line.EnteredDr;
						cfdto.LCMoney = line.AccountedCr + line.AccountedDr;
						cfdto.Currency = line.Currency;

						//通过PrivateDescSeg29,PrivateDescSeg30临时处理现金流量属性
						//现金流量项目流向
						cfdto.CashFlowItemAttr = int.Parse(line.Description.PrivateDescSeg29);// 0-流入 1-减少
						line.Description.PrivateDescSeg29 = null;
						//现金流量项目
						cfdto.CashFlowItem = new CommonArchiveDataDTOData()
						{
							Code = line.Description.PrivateDescSeg30
						};
						line.Description.PrivateDescSeg30 = null;
						
						dto.CFVoucherItems.Add(cfdto);
					}
				}
				
            }
        }
		/// <summary>
		/// 查找会计科目
		/// 如果科目不存在,会动态创建会计科目
		/// </summary>
		/// <param name="iDCodeDTO">科目编码</param>
		/// <param name="sobID">sobid</param>
		/// <param name="sobVersion">sob版本</param>
		/// <returns></returns>
		private Account FindAccount(CommonArchiveDataDTOData iDCodeDTO, long sobID, long sobVersion)
		{
			Account result;
			if (iDCodeDTO == null)
			{
				result = null;
			}
			else if (iDCodeDTO.ID > 0L)
			{
				result = Account.Finder.FindByID(iDCodeDTO.ID);
			}
			else if (iDCodeDTO.Code != string.Empty)
			{
                //动态创建会计科目
                SelectEndLevelAccount selectEndLevelAccount = new SelectEndLevelAccount();
				selectEndLevelAccount.SOB = new SetofBooks.EntityKey(sobID);
				if (sobVersion > 0L)
				{
					selectEndLevelAccount.SOBVersion = new SetofBooksVersion.EntityKey(sobVersion);
				}
				else
				{
					selectEndLevelAccount.SOBVersion = null;
				}
				selectEndLevelAccount.CombineCode = iDCodeDTO.Code;
				AccountDTO accountDTO = selectEndLevelAccount.Do();
				result = accountDTO.Account;
			}
			else
			{
				result = null;
			}
			return result;
		}
	}

	#endregion
	
	
}